package com.meego.common.pool.database;

import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

import ops.ga.config.Config;
import ops.ga.log4j.GA;

import com.jolbox.bonecp.BoneCP;
import com.jolbox.bonecp.BoneCPConfig;

public class BoneCPPool {
	private static final String driver = "com.mysql.jdbc.Driver";
	private static final String prefix = "meego.db.pool.";
	private Map<String, BoneCP> mPool;
	private static BoneCPPool sIntance;

	public static synchronized BoneCPPool getInstance() {
		if (sIntance == null) {
			sIntance = new BoneCPPool();
		}
		return sIntance;
	}

	public BoneCPPool() {
		mPool = new HashMap<String, BoneCP>();
		try {
			initPool();
		} catch (Exception e) {
			System.out.println("Shutdown Program!!!. Can't init DatabasePool");
			GA.sysmessage.error("Shutdown Program!!! Can't init DatabasePool", e);
			System.exit(1);
		}
	}

	public BoneCP getBoneCP(String aPool) {
		return mPool.get(aPool.trim().toLowerCase());
	}

	private void initPool() throws Exception {
		Class.forName(Config.getStrConfig(prefix + "driver", driver));

		StringTokenizer st = new StringTokenizer(Config.getStrConfig(prefix + "instance", "default"), ", \n\t");
		while (st.hasMoreTokens()) {
			String pName = st.nextToken().trim().toLowerCase();
			try {
				BoneCPConfig config = new BoneCPConfig();
				config.setJdbcUrl(Config.getStrConfig(prefix + pName + ".url"));
				config.setUsername(Config.getStrConfig(prefix) + pName + ".username");
				config.setPassword(Config.getStrConfig(prefix) + pName + ".password");
				config.setMinConnectionsPerPartition(Config.getIntConfig(prefix + pName + ".min", 2));
				config.setMaxConnectionsPerPartition(Config.getIntConfig(prefix + pName + ".max", 10));
				config.setTransactionRecoveryEnabled(Config.getBoolConfig(prefix + pName + ".trans.recovery", true));
				config.setDefaultAutoCommit(true);
				config.setIdleMaxAgeInSeconds(Config.getIntConfig(prefix + pName + ".idle.max.age.seconds", 10));
				config.setAcquireIncrement(Config.getIntConfig(prefix + pName + ".acquire.increment", 10));
				config.setLazyInit(Config.getBoolConfig(prefix + pName + ".lazy.init", false));
				config.setReleaseHelperThreads(Config.getIntConfig(prefix + pName + ".max", 10));
				config.setIdleConnectionTestPeriodInSeconds(Config.getIntConfig(prefix + pName + ".idle.con.test.period.seconds", 600));
				config.setCloseConnectionWatchTimeoutInMs(Config.getIntConfig(prefix + pName + ".close.con.watch.timeout.seconds", 60));
				config.setPoolName(pName);
				BoneCP pool = new BoneCP(config);
				this.mPool.put(config.getPoolName(), pool);
				GA.app.info("Created " + pName + " successfully!");
			} catch (Exception e) {
				GA.app.error("Init " + pName + "pool failure", e);
				throw e;
			}
		}
	}
}
